﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

[XLua.LuaCallCSharp]
public class SceneLoad : Singleton<SceneLoad>
{
    public string suffix = ".u3d";

    public bool isLocal = false;

    private string sceneBundleName= null;
    private string scriptBundleName=null;
    private string sceneName;
    private string scriptName;
    private string nodeName;
    private Action loadComplete;
    private Action<float> onProgress;
    private bool isSysLoad = false;
    private object param = null;
    private AsyncOperation asyncOperation;
    #region 加载场景
    /// <summary>
    /// 加载场景
    /// </summary>
    /// <param name="sceneBundleName">场景包</param>
    /// <param name="sceneName">场景名称</param>
    /// <param name="scriptBundleName">脚本包</param>
    /// <param name="scriptName">脚本名称</param>
    /// <param name="nodeName">脚本绑定节点名称，默认绑定场景第一个节点</param>
    /// <param name="complete">场景加载完成回调</param>
    /// <param name="param">向加载的场景传递参数</param>
    public void LoadScene(string sceneBundleName, string sceneName, string scriptBundleName, string scriptName,string nodeName=null, Action complete=null, object param = null)
    {
        this.isSysLoad = false;
        this.sceneBundleName = sceneBundleName;
        this.sceneName = sceneName;
        this.scriptBundleName = scriptBundleName;
        this.scriptName= scriptName;
        this.nodeName = nodeName;
        this.loadComplete = complete;
        this.param = param;
        string path = sceneBundleName + suffix;
        if (!isLocal) AssetBundleManager.Instance.LoadAssetbundle(path, OnAssetBundleLoadProgress, OnAssetBundleComplete);
        else OnAssetBundleComplete(null);

    }
    /// <summary>
    /// 异步加载场景
    /// </summary>
    /// <param name="sceneBundleName">场景包</param>
    /// <param name="sceneName">场景名称</param>
    /// <param name="scriptBundleName">脚本包</param>
    /// <param name="scriptName">脚本名称</param>
    /// <param name="nodeName">脚本绑定节点名称，默认绑定场景第一个节点</param>
    /// <param name="progress">场景加载进度</param>
    /// <param name="complete">场景加载完成调用</param>
    /// <param name="param">向加载的场景传递参数</param>
    public void LoadSceneSys(string sceneBundleName, string sceneName, string scriptBundleName, string scriptName, string nodeName = null,Action<float> progress=null, Action complete = null, object param = null)
    {
        this.isSysLoad = true;
        this.sceneBundleName = sceneBundleName;
        this.sceneName = sceneName;
        this.scriptBundleName = scriptBundleName;
        this.scriptName = scriptName;
        this.nodeName = nodeName;
        this.onProgress= progress;
        this.loadComplete = complete;
        this.param = param;
        string path = sceneBundleName + suffix;
        if (!isLocal) AssetBundleManager.Instance.LoadAssetbundle(path, OnAssetBundleLoadProgress, OnAssetBundleComplete);
        else OnAssetBundleComplete(null);
    }
    void OnAssetBundleLoadProgress(string assetBundleName, float progress)
    {

    }
    void OnAssetBundleComplete(string assetBundleName)
    {
        SceneManager.sceneLoaded += LoadSceneComplete;
        if (this.isSysLoad)
        {
            asyncOperation= SceneManager.LoadSceneAsync(sceneName);
        }
        else
        {
            SceneManager.LoadScene(sceneName);
        }
        
    }
    void LoadSceneComplete(Scene scene, LoadSceneMode sceneMode)
    {
        SceneManager.sceneLoaded -= LoadSceneComplete;
        asyncOperation = null; 
        onProgress = null;
        GameObject[] allObj = scene.GetRootGameObjects();
        GameObject binObj = allObj[0];
        foreach (GameObject obj in allObj)
        {
            Sharderunit.ResetShader(obj);
            if(!string.IsNullOrEmpty(nodeName) && obj.name == nodeName)
            {
                binObj = obj;
            }
        }
        if(!string.IsNullOrEmpty(scriptName)) GameEnvMrg.Instance.BindScrip(binObj, scriptBundleName, scriptName, param);
        loadComplete?.Invoke();
    }

    #endregion

    private void Update()
    {
        if(this.isSysLoad && asyncOperation != null)
        {
            onProgress?.Invoke(asyncOperation.progress);
        }
    }
}
